home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 August: Tool Chest / Dev.CD Aug 95 TC / Dev.CD Aug 95 TC.toast / Sample Code / Snippets / QuickDraw / ScreenDump / PictInfoTest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-28  |  12.0 KB  |  492 lines  |  [TEXT/KAHL]

  1. // Sample to demonstrate using the Picture Utilities Package
  2. //
  3. // The guts of this is in the window creation function: DoCreateWindow( PicHandle thePicture )
  4. // 
  5. // DoCreateWindow is passed a picture handle and if the global gUsePictPalette is set it
  6. // will use the pict utils package (PUP) to get the color table stored in the pict.  You could 
  7. // this source to sample direct color images, but to keep things as clear as possible this
  8. // application only deals with 8 bit images.
  9. //
  10. // We use the PUP to get the color table for the image.  This is passed into NewGWorld and it
  11. // is also used to create a palette that is attached to the window.
  12. //
  13. // Note that we use PUP to sample the image that was stored in the file.  We interrogate a
  14. // PicHandle read directly from the file.  There are also routines for sampling PixMaps,
  15. // but dont forget that if you are in an indexed color environment, and you sample a PixMap, 
  16. // if you didnt set up the color environment when your first created the PixMap, the colors
  17. // may not be as you expect.  
  18. //
  19. // To see an example of this there are two 8-bit images included with this snippet.
  20. // One is a spectral ramp, the other a green/brow ramp.  Both have approx 120 or so colors.
  21. // to see an example of what PUP may report if you didnt set the colors for a window up
  22. // properly before displaying open one of the files with the "use picture palette" item 
  23. // from the palette menu toggled off.
  24. //
  25. // in this case it will use the "wrong" set of colors to try to draw the image (it just uses
  26. // what ever the default system color table is).  If you get PUP to sample (by toggling on
  27. // the "use picture palette" item from the palette menu the picture is rendered correctly.
  28. //
  29. // Nick Thompson - May 6th 1994
  30. //
  31. //    Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  32.  
  33.  
  34. /* Constant Declarations */
  35. #include <menus.h>
  36. #include <PictUtil.h>
  37. #include <QDOffScreen.h>
  38.  
  39.  
  40. #define    WWIDTH        470
  41. #define    WHEIGHT        330
  42.  
  43. #define WLEFT        (((screenBits.bounds.right - screenBits.bounds.left) - WWIDTH) / 2)
  44. #define WTOP        (((screenBits.bounds.bottom - screenBits.bounds.top) - WHEIGHT) / 2)
  45.  
  46. #define HiWrd(aLong)    (((aLong) >> 16) & 0xFFFF)
  47. #define LoWrd(aLong)    ((aLong) & 0xFFFF)
  48.  
  49.  
  50.  
  51. enum {
  52.     mApple = 128,
  53.     mFile,
  54.     mPalette
  55. } ;
  56.  
  57. enum {
  58.     iAbout = 1
  59. } ;
  60. enum {
  61.     iOpen = 1,
  62.     iClose,
  63.     iUnused1,
  64.     iQuit = 4
  65. } ;
  66.  
  67. enum {
  68.     iUsePictPalette = 1
  69. } ;
  70.  
  71. static Boolean gQuitFlag = false ;
  72. static Point gStaggerPos = {50,50} ;
  73. static Boolean gUsePictPalette = true ;
  74.  
  75. // function prototypes
  76.  
  77. void InitToolbox( void ) ;
  78. void MainEventLoop( void ) ;
  79. void HandleKeyPress(EventRecord *event) ;
  80. void HandleOSEvent(EventRecord *event) ;
  81. void HandleMenuCommand(long menuResult) ;
  82. PicHandle DoReadPICT( short theRef, OSErr *theErr ) ;
  83. OSErr DoCreateWindow( PicHandle thePicture ) ;
  84. void AdjustMenus( void ) ;
  85.  
  86.  
  87. const RGBColor    kRGBBlack = {0, 0, 0};
  88. const RGBColor    kRGBWhite = {0xFFFF, 0xFFFF, 0xFFFF};
  89.  
  90.  
  91. main()
  92. {
  93.     InitToolbox() ;
  94.     
  95.     MainEventLoop();
  96. }
  97.  
  98.  
  99.  
  100. void InitToolbox()
  101. {
  102.     OSErr         retCode;
  103.     long         gestResponse;
  104.     Handle        menuBar = nil;
  105.     EventRecord event;
  106.     short        count;
  107.  
  108.  
  109.     InitGraf((Ptr) &qd.thePort);
  110.     InitFonts();
  111.     InitWindows();
  112.     InitMenus();
  113.     TEInit();
  114.     InitDialogs(0L);
  115.     InitCursor();
  116.  
  117.     // initialize application globals
  118.     
  119.     gQuitFlag = false;
  120.     
  121.     
  122.     menuBar = GetNewMBar(128);                // Read menus into menu bar, MBAR res id is 128
  123.     
  124.     if ( menuBar == nil )
  125.          ExitToShell();                        // if we dont have it then quit - your app 
  126.                                              // needs a dialog here
  127.  
  128.     SetMenuBar(menuBar);                    // Install menus
  129.     DisposHandle(menuBar);
  130.     
  131.     AddResMenu(GetMHandle(mApple), 'DRVR');    // Add DA names to Apple menu, ID 128
  132.  
  133.     DrawMenuBar();
  134. }
  135.  
  136.  
  137. void MainEventLoop()
  138. {
  139.     EventRecord     event;
  140.     WindowPtr       window;
  141.     short           thePart;
  142.     Rect            screenRect;
  143.     Point            aPoint = {100, 100};
  144.     GWorldPtr        theNewWorld ;
  145.     PixMapHandle    offPixMap ;
  146.     GrafPtr            oldPort ;
  147.  
  148.     while( !gQuitFlag )
  149.     {
  150.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  151.         {
  152.             AdjustMenus() ;
  153.  
  154.             switch (event.what) {
  155.                 case mouseDown:
  156.                 
  157.                     thePart = FindWindow( event.where, &window );
  158.                     
  159.                     switch( thePart ) {
  160.                         case inMenuBar: 
  161.                             HandleMenuCommand(MenuSelect(event.where));
  162.                             break;
  163.                         
  164.                         case inDrag:
  165.                     
  166.                             screenRect = (**GetGrayRgn()).rgnBBox;
  167.                             DragWindow( window, event.where, &screenRect );
  168.                             break ;
  169.                     
  170.                         case inContent:
  171.                     
  172.                             if (window != FrontWindow())
  173.                                 SelectWindow( window );
  174.                             break ;
  175.                     
  176.                         case inGoAway:
  177.                             if (TrackGoAway( window, event.where )) {
  178.                                 DisposeWindow ( window );
  179.                             }
  180.                             break ;
  181.                             
  182.                         default:
  183.                             break ;
  184.                     }
  185.                     break ;
  186.                             
  187.                         
  188.                 case updateEvt:
  189.                 
  190.                     window = (WindowPtr)event.message;
  191.                     GetPort(&oldPort ) ;    
  192.                     SetPort( window );
  193.                     
  194.                     BeginUpdate( window );
  195.                     
  196.                     // get the GWorld from the window refcon
  197.                     theNewWorld = (GWorldPtr)GetWRefCon ( window );
  198.                     offPixMap = GetGWorldPixMap( theNewWorld ) ;
  199.                     (void) LockPixels( offPixMap ) ;
  200.                     CopyBits( &((GrafPtr)theNewWorld)->portBits,
  201.                               &window->portBits,
  202.                               &window->portRect,
  203.                               &window->portRect,
  204.                               srcCopy,
  205.                               nil ) ;
  206.                     (void) UnlockPixels( offPixMap ) ;
  207.  
  208.                     EndUpdate( window );
  209.                     SetPort( oldPort ) ;
  210.                     break ;
  211.                     
  212.                 case keyDown:
  213.                 case autoKey:
  214.                     HandleKeyPress(&event);
  215.                     break;
  216.                     
  217.                 case diskEvt:
  218.                     if ( HiWrd(event.message) != noErr ) 
  219.                         (void) DIBadMount(aPoint, event.message);
  220.                     break;
  221.                     
  222.                 case osEvt:
  223.                 case activateEvt:
  224.                     break;
  225.  
  226.  
  227.             }
  228.         }
  229.     }
  230. }
  231.  
  232.  
  233. void HandleKeyPress(EventRecord *event)
  234. {
  235.     char    key;
  236.  
  237.     key = event->message & charCodeMask;
  238.     
  239.     // just check to see if we want to quit...
  240.     
  241.     if ( event->modifiers & cmdKey ) {        /* Command key down? */
  242.         HandleMenuCommand(MenuKey(key));
  243.     } 
  244. }
  245.  
  246.  
  247. void HandleMenuCommand(long menuResult)
  248. {
  249.     short        menuID;
  250.     short        menuItem;
  251.     Str255        daName;
  252.     DialogPtr    theDialog ; 
  253.     short        itemHit ;
  254.     SFTypeList    myTypes = { 'PICT' } ;
  255.     FSSpec        theFSSpec ;
  256.     PicHandle    thePicture ;
  257.     OSErr        err ;
  258.     short        theRef ;
  259.     
  260.     StandardFileReply    theSFReply ;
  261.  
  262.     menuID = HiWrd(menuResult);
  263.     menuItem = LoWrd(menuResult);
  264.     switch ( menuID ) {
  265.         case mApple:
  266.             switch ( menuItem ) {
  267.                 case iAbout:
  268.                     theDialog = GetNewDialog ( 128, nil, (WindowPtr)-1 );
  269.                     do {
  270.                         ModalDialog ( nil, &itemHit );
  271.                     } while( itemHit != ok ) ;
  272.                     DisposDialog ( theDialog );
  273.                     break;
  274.                     
  275.                 default:
  276.                     GetItem(GetMHandle(mApple), menuItem, daName);
  277.                     (void) OpenDeskAcc(daName);
  278.                     break;
  279.             }
  280.             break;
  281.         case mFile:
  282.             switch ( menuItem ) {
  283.                 case iOpen:
  284.                     // Get the file name to open
  285.                     StandardGetFile( nil, 1, myTypes, &theSFReply ) ;
  286.                     
  287.                     // did the user cancel?
  288.                     if(!theSFReply.sfGood)
  289.                         break ;
  290.                     
  291.                     // open the file
  292.                     err = FSpOpenDF( &theSFReply.sfFile, fsRdPerm, &theRef ) ;
  293.                     
  294.                     if( err != noErr )
  295.                         break ;     // should handle this properly
  296.                         
  297.                     thePicture = DoReadPICT( theRef, &err ) ;
  298.                     
  299.                     if( err != noErr )
  300.                         break ;     // should handle this properly
  301.                 
  302.                     // display the contents
  303.                     err = DoCreateWindow( thePicture ) ;
  304.                     
  305.                     break ;
  306.                     
  307.                 case iClose:
  308.                     DisposeWindow ( FrontWindow() );
  309.                     break ;
  310.                 case iQuit:
  311.                     gQuitFlag = true;
  312.                     break;
  313.             }
  314.             break;
  315.             
  316.         case mPalette:
  317.             switch ( menuItem ) {
  318.                 case iUsePictPalette :
  319.                     // toggle the check mark and the global boolean
  320.                     gUsePictPalette = !gUsePictPalette ;
  321.                     CheckItem ( GetMHandle ( mPalette ), iUsePictPalette, gUsePictPalette );
  322.                     break ;
  323.             }
  324.             break ;
  325.             
  326.         case 131:
  327.         
  328. //--------------------------- T E S T   R O U T I N E ---------------------------------
  329.             if( menuItem == 1 ) {
  330.                 // get some of the screen
  331.                 PicHandle DumpScreenArea( Rect *area ) ;        // prototype
  332.                 
  333.                 // because I have multiple monitors and I wanted to test on them
  334.                 // I set up the area below, you may want something rather different
  335.                 // YOU WILL PROBABLY NEED TO CHANGE THIS
  336.                 
  337.                 Rect area = { 0, -50, 200, 200 } ;                // area to save 
  338.  
  339.                 thePicture = DumpScreenArea( &area ) ;
  340.                 
  341.                 if( thePicture != nil )
  342.                     err = DoCreateWindow( thePicture ) ;
  343. //--------------------------- T E S T   R O U T I N E ---------------------------------
  344.  
  345.             }
  346.             break; 
  347.  
  348.     }
  349.     HiliteMenu(0);        // Unhighlight whatever MenuSelect or MenuKey hilited
  350. }
  351.  
  352. void AdjustMenus( void ) 
  353. {
  354.     WindowPtr    theWindow ;
  355.     theWindow = FrontWindow() ;
  356.     if( theWindow != nil ) {
  357.         EnableItem ( GetMHandle ( mFile ), iClose );
  358.     }
  359.     else {
  360.         DisableItem ( GetMHandle ( mFile ), iClose );
  361.     }
  362.     // make sure the check marks are correct
  363.     CheckItem ( GetMHandle ( mPalette ), iUsePictPalette, gUsePictPalette );
  364. }
  365.  
  366. PicHandle DoReadPICT( short theRef, OSErr *theErr ) 
  367. {
  368.     long        theFileSize ;
  369.     PicHandle    thePicture ;
  370.     
  371.     // pict files have a 512 byte header at the front - we dont care about this
  372.     // we can find the size of the pict by subtracting 512 bytes from the length
  373.     // of the file.  We then want to resize the handle to that and read the data
  374.     // into the resized handle.
  375.     
  376.     if(( *theErr = GetEOF( theRef, &theFileSize )) != noErr ) {
  377.         FSClose( theRef ) ;
  378.         return nil ; 
  379.     }
  380.     
  381.     if(( *theErr = SetFPos( theRef, fsFromStart, 512)) != noErr ) {
  382.         FSClose( theRef ) ;
  383.         return nil ; 
  384.     }
  385.  
  386.     theFileSize -= 512 ;
  387.     
  388.     thePicture = (PicHandle)NewHandle( theFileSize ) ;
  389.     if( thePicture == nil ) {
  390.         FSClose( theRef ) ;
  391.         *theErr = MemError() ;
  392.         return nil ;         // what ever the mem manager error was
  393.     }
  394.     
  395.     HLock( (Handle)thePicture ) ;
  396.     *theErr = FSRead( theRef, &theFileSize, (Ptr)*thePicture ) ;
  397.     HUnlock(  (Handle)thePicture ) ;
  398.     
  399.     if( *theErr != noErr ) {
  400.         FSClose( theRef ) ;
  401.         return nil ; 
  402.     }
  403.  
  404.     return thePicture ;    
  405. }
  406.  
  407. OSErr DoCreateWindow( PicHandle thePicture )
  408. {
  409.  
  410.     Rect        theRect ;
  411.     OSErr        theErr ;
  412.     GWorldPtr    theNewWorld ;
  413.     CGrafPtr    savedPort ;
  414.     GWorldPtr    savedGWorld ;
  415.     WindowPtr    theWindow ;
  416.     GDHandle    oldDevice ;
  417.     
  418.     PictInfo        thePictInfo ;
  419.     PaletteHandle    thePictPalette = nil ;
  420.     CTabHandle        thePictCTab = nil ;
  421.     
  422.     // make an offscreen environment and image the pict into this
  423.     // Make a window the size of the pict
  424.     // store a reference to the GWorld in the Refcon of the window
  425.     // invalidate the window content area.
  426.     
  427.     theRect = (**thePicture).picFrame;
  428.     
  429.     // to we want to attempt to sample the picture... 
  430.     if( gUsePictPalette ) {
  431.     
  432.         // use the picture utilities to get the palette for the window
  433.         theErr = GetPictInfo( thePicture, &thePictInfo, returnColorTable, 256, systemMethod, 0) ;
  434.         
  435.         // set up the palette and color table for later use
  436.         thePictPalette = NewPalette( 256, thePictInfo.theColorTable, pmTolerant, 0x1000 ) ;
  437.         thePictCTab = thePictInfo.theColorTable ;
  438.     }
  439.     
  440.     // we are only dealing with eight bit images here
  441.     // hence the requirement for the picture utils package to 
  442.     // return 256 colors, and we will create a gWorld 8 bits deep
  443.     
  444.     theErr = NewGWorld( &theNewWorld, 8, &theRect, thePictCTab, nil, 0L ) ;
  445.     
  446.     if( theErr != noErr ) 
  447.         return theErr ;
  448.     
  449.     // save the world
  450.     GetGWorld( &savedPort, &oldDevice ) ;
  451.     SetGWorld( theNewWorld, nil ) ;
  452.     
  453.     
  454.     RGBForeColor( &kRGBBlack ) ;        // ensure the fg and bg colors are 
  455.     RGBBackColor( &kRGBWhite ) ;        // as anticipated
  456.     EraseRect( &theRect ) ;                // clear the area for the pict
  457.     PenMode( srcCopy ) ;                // ensure the t/f mode is as expected
  458.  
  459. SetOrigin( theRect.left, theRect.top );
  460.  
  461.     // render the image into the offscreen buffer
  462.     DrawPicture( thePicture, &theRect ) ;
  463. SetOrigin( 0, 0 );
  464.     
  465.     SetGWorld( savedPort, oldDevice ) ;
  466.     
  467.     // create the window
  468.     OffsetRect( &theRect, gStaggerPos.h, gStaggerPos.v) ;
  469.     gStaggerPos.h += 16 ;
  470.     gStaggerPos.v += 16 ;        // heh - should roll these around, but you wont 
  471.                                 // create more than a couple of windows, will you  :-)
  472.                                  
  473.     theWindow  = NewCWindow( nil, &theRect, "\pplayTime", true, 
  474.                                 documentProc, (WindowPtr)-1, true, (long)theNewWorld );    
  475.                 
  476.     // and if we set up the palette earlier assign it to the window                
  477.     if( thePictPalette != nil ) {
  478.         SetPalette ( theWindow, thePictPalette, true );
  479.     }
  480.     
  481.     ActivatePalette ( theWindow );    
  482.     
  483.     // make sure it is visible
  484.     ShowWindow( theWindow ) ;
  485.     
  486.     SetGWorld( (CGrafPtr)theWindow, nil ) ;
  487.     
  488.     // invalidate the content region of the window - we don't do any drawing to it here.
  489.     InvalRect ( &theRect );
  490.     
  491.     SetGWorld( savedPort, oldDevice ) ;
  492. }